package com.yx.fx.common.config;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yx.fx.common.utils.RedisUtil;
import com.yx.fx.minio.web.utils.MinIoUtil;
import com.yx.fx.sys.db.entity.SysDictionaries;
import com.yx.fx.sys.db.entity.SysUser;
import com.yx.fx.sys.db.service.SysDictionariesService;
import com.yx.fx.sys.db.service.SysUserService;
import com.yx.fx.common.constant.BaseConstant;
import com.yx.fx.common.constant.RedisConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 启动时加载的配置
 *
 * @author 杨智杰
 * @date 2021/8/12 15:03
 */
@Slf4j
@Component
public class BaseRunConfig implements ApplicationRunner {

    @Resource
    private ServerConfig serverConfig;

    @Value("${knife4j.production:false}")
    private Boolean production;

    @Override
    public void run(ApplicationArguments args) {
        cacheConfig();
        log.info("swagger地址:" + (production ? "swagger已禁用!" : serverConfig.getSwaggerUrl()));
        log.info("-------------------------启动完毕,欢迎使用-------------------------");
    }


    @Resource
    private RedisUtil redisUtil;

    @Resource
    private SysUserService sysUserService;

    @Resource
    private SysDictionariesService dictionariesService;


    /**
     * 缓存配置
     */
    public void cacheConfig() {
        cacheBaseUser();
        cacheBaseDict();
    }

    /**
     * 用户缓存过期时长,默认25小时
     */
    @Value("${cache-config.sys-user.valid-time:90000}")
    private Long userCacheValidTime;

    /**
     * 用户缓存
     */
    @Scheduled(cron = "${cache-config.sys-user.refresh-time:0 0 2 * * ?}")
    public void cacheBaseUser() {
        List<SysUser> userList = sysUserService.list(new QueryWrapper<SysUser>().lambda().eq(SysUser::getStatus, BaseConstant.ONE));
        userList.forEach(user -> redisUtil.set(RedisConstant.SYS_USER_CACHE + user.getLoginName(), user, userCacheValidTime));
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>本次加载" + userList.size() + "条用户数据<<<<<<<<<<<<<<<<<<<<<<<<<");
    }

    /**
     * 用户缓存过期时长,默认25小时
     */
    @Value("${cache-config.sys-dict.valid-time:90000}")
    private Long dictCacheValidTime;

    /**
     * 字典缓存
     */
    @Scheduled(cron = "${cache-config.sys-dict.refresh-time:0 0 4 * * ?}")
    public void cacheBaseDict() {
        List<SysDictionaries> dictList = dictionariesService
                .list(new QueryWrapper<SysDictionaries>().lambda().eq(SysDictionaries::getStatus, BaseConstant.ONE));
        Map<String, Map<String, List<SysDictionaries>>> dictCache = new LinkedHashMap<>();
        dictList.stream().forEach(dict -> {
            if (!dictCache.containsKey(dict.getBelong())) {
                dictCache.put(dict.getBelong(), new LinkedHashMap<>());
                List<SysDictionaries> collect = dictList.stream().filter(d -> d.getBelong()
                        .equals(dict.getBelong())).collect(Collectors.toList());
                collect.stream().forEach(d -> {
                    if (!dictCache.get(dict.getBelong()).containsKey(d.getKeyword())) {
                        dictCache.get(dict.getBelong()).put(d.getKeyword(), collect.stream()
                                .filter(c -> c.getKeyword().equals(d.getKeyword())).collect(Collectors.toList()));
                    }
                });
            }
        });
        dictCache.keySet().forEach(s -> redisUtil.set(RedisConstant.SYS_DICT_CACHE + s, dictCache.get(s), dictCacheValidTime));
        log.info(">>>>>>>>>>>>>>>>>>>>>>>>>本次加载" + dictList.size() + "条字典数据<<<<<<<<<<<<<<<<<<<<<<<<<");
    }

    @Resource
    private MinIoUtil minIoUtil;

    /**
     * minio地址+端口号
     */
    @Value("${minio-config.url:http://127.0.0.1:9000}")
    public String url;

    /**
     * minio用户名
     */
    @Value("${minio-config.access-key:minioadmin}")
    public String accessKey;

    /**
     * minio密码
     */
    @Value("${minio-config.secret-key:minioadmin}")
    public String secretKey;

    /**
     * 默认文件桶的名称
     */
    @Value("${minio-config.default-bucket-name:default}")
    public String defaultBucketName;

    public void minioUtilConfig() {
        MinIoUtil.url = url;
        log.info("minio服务地址:" + MinIoUtil.url);
        MinIoUtil.accessKey = accessKey;
        log.info("minio用户名:" + MinIoUtil.accessKey);
        MinIoUtil.secretKey = secretKey;
        log.info("minio密码:" + MinIoUtil.secretKey);
        MinIoUtil.defaultBucketName = defaultBucketName;
        log.info("minio默认使用文件桶:" + MinIoUtil.defaultBucketName);
    }


    /**
     * 是否需要连接minio服务器
     */
    boolean isLink = true;

    @Scheduled(cron = "${minio-config.heartbeat.interval:30 * * * * ?}")
    public void linkMinio() {
        if (isLink) {
            minioUtilConfig();
            isLink = !minIoUtil.minioConfig();
        }
        try {
            MinIoUtil.createBucket(MinIoUtil.defaultBucketName);
            log.info("minio心跳检测正常!");
        } catch (Exception e) {
            log.error("minio服务器连接丢失!", e);
            isLink = true;
        }
    }

}
